package com.kg.fiber.service.pcie8622;

import java.util.ArrayList;
import java.util.List;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;

public class Pcie8622Sdk {
	
	public static final int PCIe8622_GATEMODE_POSITIVE_0 = 0x00;
	public static final int PCIe8622_GATEMODE_RISING_1 = 0x01;
	public static final int PCIe8622_GATEMODE_POSITIVE_2 = 0x02;
	public static final int PCIe8622_GATEMODE_POSITIVE_3 = 0x03;
	public static final int PCIe8622_GATEMODE_POSITIVE_4 = 0x04;
	public static final int PCIe8622_GATEMODE_RISING_5 = 0x05;
	
	// ad_mode AD 采样模式
	public static final int PCIE8622_ADMODE_SEQUENCE = 0x00; // 连续采集模式
	public static final int PCIE8622_ADMODE_GROUP = 0x01;    // 分组采集模式
	
	// input_range
	public static final int PCIE8622_INPUT_N10000_P10000mV = 0x00; // ±10000mV
	public static final int PCIE8622_INPUT_N5000_P5000mV = 0x01;   // ±5000mV
	public static final int PCIE8622_INPUT_N2500_P2500mV = 0x02;   // ±2500mV
	public static final int PCIE8622_INPUT_0_P10000mV = 0x03;      // 0~10000mV
	public static final int PCIE8622_INPUT_0_P5000mV = 0x04;       // 0~5000mV
	
	// rangechan
	public static final int PCIE8622_GAINS_1MULT = 0x00;  // 1倍增�?
	public static final int PCIE8622_GAINS_2MULT = 0x01;  // 2倍增�?
	public static final int PCIE8622_GAINS_5MULT = 0x02;  // 4倍增�?
	public static final int PCIE8622_GAINS_10MULT = 0x03; // 8倍增�?
	
	// triggermode
	public static final int PCIE8622_TRIGMODE_SOFT = 0x00; // 软件触发(属于内触�?)
	public static final int PCIE8622_TRIGMODE_POST = 0x01; // 硬件后触�?(属于外触�?)
	
	// triggersource 
	public static final int PCIE8622_TRIGSRC_ATR = 0x01; // 选择 ATR 作为触发�?
	public static final int PCIE8622_TRIGSRC_DTR = 0x02; // 选择 DTR 作为触发�?
	
	// trigertype
	public static final int PCIE8622_TRIGTYPE_EDGE = 0x00;  // 边沿触发
	public static final int PCIE8622_TRIGTYPE_PULSE = 0x01; // 脉冲触发(电平)
	
	// triggerdir
	public static final int PCIE8622_TRIGDIR_NEGATIVE = 0x00;    // 负向触发(低脉�?/下降沿触�?)
	public static final int PCIE8622_TRIGDIR_POSITIVE = 0x01;    // 正向触发(高脉�?/上升沿触�?)
	public static final int PCIE8622_TRIGDIR_POSIT_NEGAT = 0x02; // 正负方向均有�?
	
	// clocksource	
	public static final int PCIE8622_CLOCKSRC_IN = 0x00;  // 内部时钟定时触发
	public static final int PCIE8622_CLOCKSRC_OUT = 0x01; // 外部时钟定时触发
	
	// bclockoutput
	public static final int PCIE8622_CLOCKOUT_DISABLE = 0x00; // 禁止本卡上的自带时钟向外输出
	public static final int PCIE8622_CLOCKOUT_ENABLE = 0x01;  // 允许本卡上的自带时钟向外输出
	
	// groundingmode	
	public static final int PCIE8622_GNDMODE_SE = 0x00; // 单端方式(SE:Single end)
	public static final int PCIE8622_GNDMODE_DI = 0x01; // 双端方式(DI:Differential)
	
	// 用于AD采样的实际硬件参�?
	public static class  PCIE8622_PARA_AD extends Structure{
		public int FirstChannel;   // 首�?�道[0,31]
		public int Gains;          // 增益设置
		public int LastChannel;    // 末�?�道[0,31],要求末�?�道必须大于或等于首通道
		public int ADMode;         // AD模式选择(连续/分组方式)
		public int TriggerMode;    // 触发模式选择
		public int TriggerSource;  // 触发源�?�择
		public int TriggerType;    // 触发类型选择(边沿触发/脉冲触发)
		public int TriggerDir;     // 触发方向选择(正向/负向触发)
		public int ClockSource;    // 时钟源�?�择(�?/外时钟源)
		public int bClockOutput;   // 允许时钟输出
		public int GroundingMode;  // 接地方式(单端或双端�?�择)
		public int Frequency;      // 采集频率,单位为Hz
		public int GroupInterval;  // 分组时的组间间隔(单位：微�?)[1, 419430]
		public int LoopsOfGroup;   // 组内循环次数[1, 65535]
		public int InputRange;     // 模拟量输入量程范�?
		public int TrigLevelVolt;  // 触发电平(0mV ~10000mV)
		public static class ByReference extends PCIE8622_PARA_AD implements Structure.ByReference{
			
		}
		public static class ByValue extends PCIE8622_PARA_AD implements Structure.ByValue{
			
		}
		@Override
		protected List<String> getFieldOrder() {
			List<String> a = new ArrayList<String>();
			a.add("FirstChannel");
			a.add("Gains");
			a.add("LastChannel");
			a.add("ADMode");
			a.add("TriggerMode");
			a.add("TriggerSource");
			a.add("TriggerType");
			a.add("TriggerDir");
			a.add("ClockSource");
			a.add("bClockOutput");
			a.add("GroundingMode");
			a.add("Frequency");
			a.add("GroupInterval");
			a.add("LoopsOfGroup");
			a.add("InputRange");
			a.add("TrigLevelVolt");
			return a;
		}

	}
	
	public static class DO_PARA extends Structure{
		public byte[] do_enable=new byte[16];
		public int Reserved0;
		public static class ByReference extends DO_PARA implements Structure.ByReference{
			
		}
		public static class ByValue extends DO_PARA implements Structure.ByValue{
			
		}
		
		@Override
		protected List<String> getFieldOrder() {
			List<String> a = new ArrayList<String>();
			a.add("do_enable");
			a.add("Reserved0");
			return a;
		}

	}
	
	public static class DI_PARA extends Structure{
		public byte[] di_data=new byte[16];
		public int Reserved0;
		public static class ByReference extends DI_PARA implements Structure.ByReference{
			
		}
		public static class ByValue extends DI_PARA implements Structure.ByValue{
			
		}
		
		@Override
		protected List<String> getFieldOrder() {
			List<String> a = new ArrayList<String>();
			a.add("di_data");
			a.add("Reserved0");
			return a;
		}

	}
	
	public DO_PARA getDOPara(){
		return new DO_PARA();
	}
	public DI_PARA getDIPara(){
		return new DI_PARA();
	}
	
	public interface Clibrary extends Library{
		Clibrary INSTANCE = (Clibrary)Native.loadLibrary("pcie8622",Clibrary.class);
		
		// 打开设备
		Pointer pcie_device_open(int devicelgcid);
		
		// 关闭设备
		int pcie_device_close(Pointer hDevice);
		
		// 获取当前设备�?
		int pcie_get_devicecount(Pointer hDevice);
		
		// 获取设备的�?�辑ID还有设备ID
		int pcie_get_devicecurrentid(Pointer hDevice, int deviceid,int logicid);
		
		// 获取设备的版本信息�??
		int pcie_get_device_information(Pointer hDevice,int version);
		
		// 使能AD
		int pcie_enable_ad(Pointer hDevice);
		
		// 使能AD半满中断
		int pcie_enable_halfirq(Pointer hDevice);
		
		// 复位AD
		int pcie_ad_reset(Pointer hDevice);
		
		// 清除AD的FIFO
		int pcie_ad_clear_fifo(Pointer hDevice);
		
		// AD功能初始�?
		int pcie_ad_init(Pointer hDevice,PCIE8622_PARA_AD.ByReference pcie_ad_para);
		
		// 半满读取数据
		int pcie_read_ad_half(Pointer hDevice,short[] buffer,int count);
		
		// 非空读取
		int pcie_read_ad_noirq(Pointer hDevice,short[] buffer,int lenth,int retlen[]);
		
		// 计数器功能的设置
		int pcie_set_device_ctr(Pointer hDevice,int ctr_mode,int cntcount);
		
		// 获取计数器当前计数�??
		int pcie_get_ctr_count(Pointer hDevice,long[] count_ctr);
		
		// do势能输出
		int pcie_do_enable(Pointer hDevice,DO_PARA pdo_para);
		
		// 获取DI的状�?
		int pcie_di_read_data(Pointer hDevice,DI_PARA pdi_para);
		
		// 获取DO的状�?
		int pcie_do_read_data(Pointer hDevice,DO_PARA pdo_para);
		
		// 读取EEPROM的数�?
		int pcie_read_e2prom(Pointer hDevice,int e2p_addr,int e2p_data);
		
		// 写EEPROM
		int pcie_write_e2prom(Pointer hDevice,int e2p_addr,int e2p_data);
		
		// 更新EEPROM的数据，使用pcie_write_e2prom函数后，将数据保存到eeprom中使用此函数
		int pcie_update_e2prom(Pointer hDevice);
		
		// 读取ADfifo的状�?
		// 返回值，三位有效，D0 0:FIFO非空 1:FIFO已空
		// D1 0:FIFO未半�? 1:半满
		// D2 0:FIFO未溢�? 1:FIFO溢出
		int pcie_read_reg(Pointer hDevice,int addr);
		
		// 去使能半�?
		int pcie_disable_halfirq(Pointer hDevice);
		
		// 停止AD
		int pcie_stop_ad(Pointer hDevice);
}
}
